package org.realman.sprites{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.ui.KeyLocation;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
	
	public class GameStage extends Sprite{
		
		private const REALMAN_SPEED:Number = 10;
		
		private const MONSTER_SPEED:Number = 5;
		
		private const INIT_MONSTER_POS:Array = ["left", "right", "top", "bottom"];
		
		private var realman:RealMan;
		
		private var monsters:Array = [];
		
		private var timer:Timer;
		
		public function GameStage(){
			super();
			
			addEventListener(Event.ADDED_TO_STAGE, drawStage);
		}
		
		private function drawStage(event:Event):void{
			removeEventListener(Event.ADDED_TO_STAGE, drawStage);
			initRealMan();
			monsters = createMonsters();
			
			var g:Graphics = this.graphics;
			g.beginFill(0x000000);
			g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			g.endFill();
		}
		
		public function start():void{
			drawSpirtes();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, startToMoveRealMan);
			stage.addEventListener(KeyboardEvent.KEY_UP, stopRealMan);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			activateTimer();
		}
		
		public function drawSpirtes():void{
			this.addChild(realman);
			
			for each(var monster:Monster in monsters){
				this.addChild(monster);
			}
		}
		
		private function initRealMan():void{
			realman = new RealMan();
			realman.x = stage.stageWidth/2;
			realman.y = stage.stageHeight/2;
		}
		
		private function createMonsters():Array{
			var monsterArr:Array = [];
			for(var i:int = 0; i < 10; i++){
				var monster:Monster = new Monster(4, 0);
				var pos:Point = getInitMonsterPos();
				monster.x = pos.x;
				monster.y = pos.y;
				
				monsterArr.push(monster);
			}
			return monsterArr;
		}
		
		private function getInitMonsterPos():Point{
			var posIndex:int = int(Math.round(Math.random() * 3));
			var pos:Point;
			if(INIT_MONSTER_POS[posIndex] == "left")
				pos = new Point(0, Math.random() * stage.stageHeight);
			else if(INIT_MONSTER_POS[posIndex] == "right")
				pos = new Point(stage.stageWidth, Math.random() * stage.stageHeight);
			else if(INIT_MONSTER_POS[posIndex] == "top")
				pos = new Point(Math.random() * stage.stageWidth, 0);
			else if(INIT_MONSTER_POS[posIndex] == "bottom")
				pos = new Point(Math.random() * stage.stageWidth, stage.stageHeight);
			return pos;
		}
		
		private function activateTimer():void{
			if(timer == null)
				timer = new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER, addMonsters);
			timer.start();
		}
		
		private function deactivateTimer():void{
			if(timer){			
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, addMonsters);
				timer = null;
			}
		}
		
		private function startToMoveRealMan(event:KeyboardEvent):void{
			switch(event.keyCode){
				case Keyboard.UP:
					realman.vx = 0;
					realman.vy = -REALMAN_SPEED;
					break;
				
				case Keyboard.DOWN:
					realman.vx = 0;
					realman.vy = REALMAN_SPEED;
					break;
				
				case Keyboard.LEFT:
					realman.vx = -REALMAN_SPEED;
					realman.vy = 0;
					break;
				
				case Keyboard.RIGHT:
					realman.vx = REALMAN_SPEED;
					realman.vy = 0;
					break;
				
				default:
					break;
			}
		}
		
		private function stopRealMan(event:KeyboardEvent):void{
			if(event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN){
				realman.vy = 0;
			}
			else if(event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT){
				realman.vx = 0;
			}
		}
		
		private function enterFrameHandler(event:Event):void{
			realman.move();
			if(monstersChaseMan()){
				stopMonsters();	
				deactivateTimer();
			}
		}
		
		private function monstersChaseMan():Boolean{
			var isCatch:Boolean = false;
			for each(var monster:Monster in monsters){
				moveMonster(monster);
				if(isCatchRealMan(monster)){
					isCatch = true;
					break;
				}
			}
			return isCatch;
		}
		
		private function moveMonster(monster:Monster):void{
			monster.move();
			
			var left:Number = 0;
			var right:Number = stage.stageWidth;
			var top:Number = 0;
			var bottom:Number = stage.stageHeight;
			
			if(monster.x + monster.size > right){
				monster.x = right - monster.size;
				monster.vx *= -1;
				monster.angle = calMonsterRealManAngle(monster);
			}
			else if(monster.x - monster.size < left){
				monster.x = left + monster.size;
				monster.vx *= -1;
				monster.angle = calMonsterRealManAngle(monster);
			}
			
			if(monster.y + monster.size > bottom){
				monster.y = bottom - monster.size;
				monster.vy *= -1;
				monster.angle = calMonsterRealManAngle(monster);
			}
			else if(monster.y - monster.size < top){
				monster.y = top + monster.size;
				monster.vy *= -1;
				monster.angle = calMonsterRealManAngle(monster);
			}
		}
		
		private function calMonsterRealManAngle(monster:Monster):Number{
			var dx:Number = realman.x - monster.x;
			var dy:Number = realman.y - monster.y;
			return Math.atan2(dy, dx);
		}
		
		private function isCatchRealMan(monster:Monster):Boolean{
			return monster.hitTestObject(realman);
		}
		
		private function stopMonsters():void{
			for each(var monster:Monster in monsters){
				monster.stop();
			}
		}
		
		private function addMonsters(event:TimerEvent):void{
			var monsterArr:Array = createMonsters();
			monsters = monsters.concat(monsterArr);
			for each(var monster:Monster in monsterArr){
				addChild(monster);
			}
			
		}
	}
}